public class TreeNode
{
    public TreeNode(string nodeName)
    {
        NodeName = nodeName;
        Parents = new List<TreeNode>();
        Childrens = new List<TreeNode>();
    }

    public string NodeName { get; set; }
    public NodeType NodeType { get; set; } = NodeType.Default;
    public NodeStatus NodeStatus { get; set; } = NodeStatus.Normal;
    public List<TreeNode> Parents { get; set; }
    public List<TreeNode> Childrens { get; set; }

    public void SetParents(List<TreeNode> parents)
    {
        if (!parents.Any())
        {
            NodeType = NodeType.Root;
            return;
        }
        Parents.AddRange(parents);
    }

    public void SetChildrens(List<TreeNode> childrens)
    {
        if (!childrens.Any())
        {
            NodeType = NodeType.Leaf;
            return;
        }
        Childrens.AddRange(childrens);
    }

    /// <summary>
    /// 移除无效边
    /// </summary>
    /// <param name="treeNodes"></param>
    public static void ClearInvalidedSides(List<TreeNode> treeNodes, List<TreeNode> originTreeNodes)
    {
        //同层级移除完毕
        foreach (var treeNode in treeNodes)
        {
            treeNode.RemoveInvalidedNode(originTreeNodes);
        }

        foreach (var treeNode in treeNodes)
        {
            if (treeNode.NodeType == NodeType.Leaf)
            {
                continue;
            }

            var childrenNames = treeNode.Childrens.Select(c => c.NodeName).ToList();
            var childrenNodes = originTreeNodes.Where(o => childrenNames.Contains(o.NodeName)).ToList();
            ClearInvalidedSides(childrenNodes, originTreeNodes);
        }
    }

    /// <summary>
    /// 移除重复节点
    /// </summary>
    public void RemoveInvalidedNode(List<TreeNode> originTreeNodes)
    {
        foreach (var children in Childrens)
        {
            var waitRemoveNodeNames = new List<string>();

            //同级节点
            foreach (var peerNode in Childrens.Where(c => c.NodeName != children.NodeName && c.NodeStatus == NodeStatus.Normal))
            {
                var isExistedNode = CheckIsExistedNode(children, peerNode, originTreeNodes);
                if (isExistedNode)
                {
                    Console.WriteLine($"Duplicate side: {children.NodeName}");
                    children.NodeStatus = NodeStatus.Invalid;
                }
            }
        }
    }

    /// <summary>
    /// 嵌套检查子节点中是否存在同名节点
    /// </summary>
    /// <param name="currentNode"></param>
    /// <param name="targetNode"></param>
    /// <returns></returns>
    public bool CheckIsExistedNode(TreeNode currentNode, TreeNode targetNode, List<TreeNode> originTreeNodes)
    {
        var originTargetNode = originTreeNodes.Where(t => t.NodeName == targetNode.NodeName).First();
        if (currentNode.NodeName == originTargetNode.NodeName)
        {
            return true;
        }

        foreach (var childrenNode in originTargetNode.Childrens)
        {
            var isExisted = CheckIsExistedNode(currentNode, childrenNode, originTreeNodes);
            if (isExisted)
            {
                return true;
            }
        }

        return false;
    }

    /// <summary>
    /// 分析各节点的类型
    /// </summary>
    /// <param name="treeNodes"></param>
    public static void AnalyseNodeType(List<TreeNode> treeNodes)
    {
        foreach (var treeNode in treeNodes)
        {
            Console.WriteLine($"CurrentNode: {treeNode.NodeName}, NodeType: {treeNode.NodeType} *");

            foreach (var parent in treeNode.Parents)
            {
                parent.NodeType = treeNodes.Where(t => t.NodeName == parent.NodeName).First().NodeType;
                Console.WriteLine($"->ParentNode: {parent.NodeName}, NodeType: {parent.NodeType}");
            }
            foreach (var children in treeNode.Childrens)
            {
                children.NodeType = treeNodes.Where(t => t.NodeName == children.NodeName).First().NodeType;
                Console.WriteLine($"->ChildrenNode: {children.NodeName}, NodeType: {children.NodeType}");
            }
        }
    }
}

public enum NodeType
{
    Default,
    Root,
    Leaf,
}

public enum NodeStatus
{
    Normal,
    Invalid
}